package com.zhrj.exam.Task;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhrj.exam.entity.BladeUser;
import com.zhrj.exam.service.BladeUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.*;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Component
@Slf4j
public class UserInfoSyncTask {
    @Resource
    private ObjectMapper objectMapper;
    private static final String url = "http://localhost:80/blade-user/user-list?pageNum=1&pageSize=10";
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private BladeUserService bladeUserService;
    private final String TOKEN = "accessToken";
    private final String Type = "tokenType";
    @PostConstruct
    public void init() throws JsonProcessingException {
        log.info("项目启动，自动运行一次...");
        syncUserInfo();
    }

    @Scheduled(cron = "0 0 3 * * ?")
    public void syncUserInfo() throws JsonProcessingException {
        log.info("每天 03:00:00 运行...");
        String token = (String) redisTemplate.opsForValue().get(TOKEN);
        String type = (String) redisTemplate.opsForValue().get(Type);
        log.info("token:{}",token);
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.set("blade-auth", type + " " + token);
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        String clientId = "saber";
        String clientSecret = "saber_secret";
        String auth = clientId + ":" + clientSecret;
        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
        httpHeaders.set("Authorization", encodedAuth);
        HttpEntity<String> httpEntity = new HttpEntity<>(httpHeaders);
        ResponseEntity<String> response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                httpEntity,
                String.class
        );
        log.info("接口响应:{}",response);
        JsonNode jsonNode = objectMapper.readTree(response.getBody().toString());
        JsonNode jsonNode1 = jsonNode.get("records");
        System.out.println(jsonNode1);
        List<BladeUser> users = objectMapper.convertValue(jsonNode1, new TypeReference<List<BladeUser>>() {
        });

        if(users == null){
            log.info("token失效，请重新登录");
            return;
        }


        /*
        * 增量更新
        * */
        List<BladeUser> list = bladeUserService.list();
        Map<Long, BladeUser> userMap = users.stream().collect(Collectors.toMap(BladeUser::getId, Function.identity()));
        int deleteCount = 0;

        for (BladeUser localUser : list) {
            BladeUser remoteUser = userMap.get(localUser.getId());
            if(remoteUser == null){
                deleteCount++;
                localUser.setIsDeleted(1);
                bladeUserService.update(localUser);
                continue;
            }
            if(!localUser.getUpdateTime().equals(remoteUser.getUpdateTime())){
                remoteUser.setIsDeleted(0);
                bladeUserService.update(remoteUser);
            }
        }
        log.info("逻辑删除" + deleteCount + "条");

        /*
        * 增量插入
        * */
        List<Long> existUserIds = bladeUserService.getExistUserIds();  // 例如根据 userId
        List<BladeUser> newUsers = users.stream()
                .filter(user -> !existUserIds.contains(user.getId()))  // 根据唯一键进行过滤
                .collect(Collectors.toList());

        if (!newUsers.isEmpty()) {
            bladeUserService.batchInsertUsers(newUsers);
            log.info("成功插入新用户数：" + newUsers.size());
        } else {
            log.info("没有需要新增的用户");
        }
        bladeUserService.exportUsersToExcel();
    }

}

